package com.group.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.base.view.BaseResult;
import com.base.view.GeneralResult;
import com.base.view.ListResult;
import com.group.model.*;
import com.group.util.NoteException;
import com.group.util.WeiXinUtils;

/**
 * 第三方竞猜相关接口
 * 
 * @author zhaolei
 *
 */
@Controller
public class CasinoController extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(CasinoController.class);

	String appKey = "fengguocaijingbcquizh5";
	String secret = "0d1882d35ab2fc0241cae7eba7c9afac";

	/**
	 * 获取用户跳转到竞猜的链接
	 * 
	 * @param request HttpServletRequest
	 * @return String
	 * @throws Exception e
	 */
	@GetMapping("/casino/url")
	@ResponseBody
	public GeneralResult<String> casinoUrl(HttpServletRequest request) throws Exception {
		User user = getUser(request);
		Long timeStamp = System.currentTimeMillis() / 1000;

		UserTicker ut = tickerService.getUserTicker(user.getId(), "wecc");

		Double num = ut.getNum();

		// 添加竞猜币
		CasinoInfo info = beanDao.quickQueryOne(CasinoInfo.class, "userId", user.getId());
		if (info == null)
			throw new NoteException("请先创建竞猜账户后进入");
		num += info.getNum();

		String credits = num.intValue() + "";

		String uid = user.getId().toString();
		String channel = "5";
		String name = URLEncoder.encode(user.getName(), "utf-8");
		String url = "http://h.ucp310.com/m/login/auto?name=" + name + "&channel=" + channel + "&uid=" + uid + "&credits=" + credits + "&appKey=" + appKey + "&timeStamp=" + timeStamp + "&sign=";

		String str = appKey + channel + credits + user.getName() + timeStamp + uid + secret;

		String sign = WeiXinUtils.getMD5Code(str);
		url += sign;

		logger.info("str = " + str + " \n sign = " + sign);

		return new GeneralResult<String>().setValue(url);
	}

	/**
	 * 博彩方查询用户钱包
	 * @param uid uid
	 * @return Double
	 */
	@GetMapping("/casino/credit/query")
	@ResponseBody
	public GeneralResult<Double> queryUserTicker(Long uid) {
		List<UserTicker> uts = userDao.queryUserTicker(uid, "wecc");

		// 钱包余额
		Double num = 0d;
		if (uts != null && uts.size() > 0)
			num = uts.get(0).getNum();

		// 添加竞猜币
		CasinoInfo info = beanDao.quickQueryOne(CasinoInfo.class, "userId", uid);
		if (info == null)
			throw new NoteException("请先创建竞猜账户后进入");
		num += info.getNum();

		return new GeneralResult<Double>().setValue(num);
	}

	/**
	 * 博彩方减少,增加用户余额
	 * 
	 * @param uid uid
	 * @param credits credits
	 * @param timeStamp 时间戳
	 * @param orderNo 订单号
	 * @param sign 签名
	 * @return BaseResult
	 */
	@GetMapping("/casino/credit/add")
	@ResponseBody
	@Transactional
	public synchronized BaseResult addCredit(Long uid, String credits, Long timeStamp, String orderNo, String sign) {
		logger.info("uid=" + uid + " , credits = " + credits + ",timeStamp = " + timeStamp + " , orderNo = " + orderNo + " , sign = " + sign);
		// 验证签名
		String str = credits + orderNo + timeStamp + uid + secret;

		String baseSign = WeiXinUtils.getMD5Code(str);
		if (!baseSign.equals(sign)) {
			logger.info("签名错误 ");
			throw new NoteException("签名错误");
		}

		User user = beanDao.quickQueryOneById(User.class, uid);
		if (user == null) {
			logger.info("uid = " + uid + " 用户不存在");
			throw new NoteException("用户不存在");
		}

		Double credit = Double.parseDouble(credits);
		// 记录日志
		CasinoLog log = new CasinoLog();
		log.setOrderNo(orderNo);
		if (beanDao.queryOne(log) != null) {
			logger.info("已经处理过订单 编号为:" + orderNo);
			throw new NoteException("已经处理过订单 编号为:" + orderNo);
		}
		log.setUserId(uid);
		log.setUserName(user.getName());
		log.setNum(credit);
		log.setDate(df.format(new Date()));
		beanDao.save(log);

		CasinoInfo info = beanDao.quickQueryOne(CasinoInfo.class, "userId", uid);
		if (info == null) {
			logger.info("uid 对应的账户不存在 : " + uid);
			throw new NoteException("请先创建竞猜账户后进入");
		}
		if (credit < 0) {
			// 处理扣减币
			// 要扣除的金额 正数
			Double amount = -credit;
			if (info.getNum() >= amount) {
				// 竞猜币足够
				info.setNum(info.getNum() - amount);
				beanDao.save(info);

			} else {
				// 竞猜币不足,扣除余额
				UserTicker ut = tickerService.getUserTicker(uid, "wecc");
				if (amount > (ut.getNum() + info.getNum())) {
					logger.info("uid = " + uid + " 余额不足,不能下注");
					throw new NoteException("余额不足,不能下注");
				}
				// 扣除余额
				tickerService.addTicker(user.getId(), "wecc", -(amount - info.getNum()), "竞猜币不足扣除钱包");

				info.setNum(0d);
				beanDao.save(info);
			}

			// 下注额度的5% 增加奖池

		} else {
			// 增加竞猜币余额
			info.setNum(info.getNum() + credit);
			beanDao.save(info);
		}

		return new BaseResult();
	}

	/**
	 * 查询用户竞猜信息,包括球队 币 奖池等
	 * @param request HttpServletRequest
	 * @param channel channel
	 * @return CasinoInfo
	 */
	@GetMapping("/casino/info")
	@ResponseBody
	public GeneralResult<CasinoInfo> queryMyCasinoInfo(HttpServletRequest request, Integer channel) {
		if (channel == null) {
			throw new NoteException("渠道不能为空");
		}

		User user = getUser(request);
		Long userId = user.getId();

		CasinoInfo info = beanDao.quickQueryOne(CasinoInfo.class, "userId", userId);

		if (info == null) {
			info = new CasinoInfo();

			info.setNum(getSystemParaValueDouble("casinoInitToker"));
			info.setUserId(userId);
			beanDao.save(info);

			if (user.getChannel() == null) {
				user.setChannel(channel);
				beanDao.save(user);
			}

		}

		// 补充钱包
		info.setTicker(tickerService.getUserTicker(userId, "wecc").getNum());

		// 补充奖池
		info.setCashPool(tickerDao.getCasinoPool());

		// 补充球队支持人数
		if (info.getTeam() != null) {
			CasinoTeam team = beanDao.quickQueryOne(CasinoTeam.class, "team", info.getTeam());
			info.setTeamSupport(team.getNum());
		}

		// 是否有分享机会
		info.setHasRedpack(casinoService.hasRedPack(userId));

		return new GeneralResult<CasinoInfo>().setValue(info);
	}

	/**
	 * 支持球队
	 * 
	 * @param userId 用户id
	 * @param team 球队
	 * @return BaseResult
	 */
	@GetMapping("/casino/team/support")
	@ResponseBody
	public BaseResult teamSupport(Long userId, String team) {
		CasinoTeam cteam = beanDao.quickQueryOne(CasinoTeam.class, "team", team);

		if (cteam == null) {
			cteam = new CasinoTeam();
			cteam.setTeam(team);
			cteam.setNum(0);
		}

		Random r = new Random();
		cteam.setNum(cteam.getNum() + r.nextInt(10) + 1);
		beanDao.save(cteam);

		// 添加我支持的球队
		CasinoInfo info = beanDao.quickQueryOne(CasinoInfo.class, "userId", userId);
		info.setTeam(team);
		beanDao.save(info);

		return new BaseResult();
	}

	/**
	 * 提现接口
	 * 
	 * @param request HttpServletRequest
	 * @param num 金额
	 *            提现金额
	 * @return BaseResult
	 */
	@GetMapping("/casino/cash")
	@ResponseBody
	@Transactional
	public synchronized BaseResult cash(HttpServletRequest request, Double num) {
		User user = getUser(request);

		if (num < 1500) {
			throw new NoteException("不足1500 不能提现");
		}

		// 扣除竞猜币
		CasinoInfo info = beanDao.quickQueryOne(CasinoInfo.class, "userId", user.getId());
		if (num > info.getNum())
			throw new NoteException("余额不足 不能提现");

		info.setNum(info.getNum() - num);
		beanDao.save(info);

		// 提现
		tickerService.addTicker(user.getId(), "wecc", num, "竞猜提现到钱包");

		return new BaseResult();
	}

	/**
	 * 查询最新的10条提现记录
	 * 
	 * @return UserTickerLog
	 */
	@GetMapping("/casino/cash/log")
	@ResponseBody
	public ListResult<UserTickerLog> qqueryCashLog() {

		return new ListResult<UserTickerLog>().setList(tickerDao.queryCasinoCashLog());
	}

	/**
	 * 生成分享红包
	 * 
	 * @param userId 用户id
	 * @return CasinoRedpack
	 */
	@GetMapping("/casino/redpack/add")
	@ResponseBody
	public GeneralResult<CasinoRedpack> addCasinoRedpack(Long userId) {
		if (casinoService.hasRedPack(userId)) {
			CasinoRedpack rp = new CasinoRedpack();
			rp.setDate(df.format(new Date()));
			rp.setDraw(0);
			rp.setUserId(userId);
			rp.setUuid(UUID.randomUUID().toString());
			beanDao.save(rp);
			return new GeneralResult<CasinoRedpack>().setValue(rp);
		} else {
			throw new NoteException("没有分享红包机会");
		}

	}

	/**
	 * 红包抽奖
	 * @param uuid uuid
	 * @param request HttpServletRequest
	 * @return CasinoRedpackLog
	 */
	@GetMapping("/casino/redpack/lottery")
	@ResponseBody
	public synchronized GeneralResult<CasinoRedpackLog> lottery(String uuid, HttpServletRequest request) {
		User user = getUser(request);
		CasinoRedpack crp = beanDao.quickQueryOne(CasinoRedpack.class, "uuid", uuid);
		if (uuid == null) {
			throw new NoteException("红包不存在");
		}

		Long casinoRedpackId = crp.getId();

		CasinoRedpackLog para = new CasinoRedpackLog();
		para.setCasinoRedpackId(casinoRedpackId);
		para.setUserId(user.getId());
		CasinoRedpackLog exist = beanDao.queryOne(para);
		// 已经抽过 返回抽奖结果
		if (exist != null)
			return new GeneralResult<CasinoRedpackLog>().setValue(exist);

		// 没有次数不能抽奖
		CasinoRedpack rp = beanDao.quickQueryOneById(CasinoRedpack.class, casinoRedpackId);
		if (rp == null)
			throw new NoteException("红包不存在");

		if (rp.getDraw().intValue() == 11) {
			throw new NoteException("红包已领完");
		}

		Random r = new Random();

		int remain = 110 - rp.getDrawAmount();

		int remainPerson = 11 - rp.getDraw();

		// 保证没人至少1个
		remain = remain - remainPerson * 3;

		int amount = r.nextInt(remain) + 1;

		if (rp.getDraw().intValue() == 10) {
			// 最后一个拿全部
			amount = 110 - rp.getDrawAmount();
		}

		// 保存抽奖记录
		para.setUserName(user.getName());
		para.setNum(amount);
		para.setUserHeadimage(user.getHeadimage());
		beanDao.save(para);

		// 更新红包领取数据
		rp.setDraw(rp.getDraw() + 1);
		rp.setDrawAmount(rp.getDrawAmount() + amount);
		beanDao.save(rp);

		CasinoInfo info = beanDao.quickQueryOne(CasinoInfo.class, "userId", user.getId());
		if (info == null) {

		}
		info.setNum(info.getNum() + amount);
		beanDao.save(info);

		return new GeneralResult<CasinoRedpackLog>().setValue(para);
	}

	/**
	 * 查询
	 * 
	 * @param casinoRedpackId casinoRedpackId
	 * @return CasinoRedpackLog
	 */
	@GetMapping("/casino/redpack/log")
	@ResponseBody
	public ListResult<CasinoRedpackLog> queryCasinoRedpackLog(Long casinoRedpackId) {

		return new ListResult<CasinoRedpackLog>().setList(beanDao.quickQueryList(CasinoRedpackLog.class, "casinoRedpackId", casinoRedpackId));
	}

	/**
	 * 发奖
	 * 
	 * @return BaseResult
	 */
	@GetMapping("/casino/test134")
	@ResponseBody
	public BaseResult test() {
		List<CasinoInfo> infos = beanDao.quickQueryList(CasinoInfo.class, "team", "法国");

		for (CasinoInfo info : infos) {
			info.setNum(info.getNum() + 137);
			beanDao.save(info);
		}

		return new BaseResult();
	}

}
